import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.HashSet;
import java.util.Set;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;


public class Model {

	private Set<Student> students;
	private XStream xstream = new XStream(new DomDriver());
	
	private void serializeSet(Set<Student> students, OutputStream output) throws IOException
	{
		XStream xoutstream = new XStream(new DomDriver());
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(output));
        ObjectOutputStream out = xoutstream.createObjectOutputStream(writer, "hashSet");
        out.writeObject(students);
        out.close();
	}
	
	private void deserializeSet(InputStream input) throws IOException, ClassNotFoundException
	{
        BufferedReader reader = new BufferedReader(new InputStreamReader(input));
        ObjectInputStream in = xstream.createObjectInputStream(reader);
        students = (Set<Student>) in.readObject();
	}
	
	public void addStudent(int numberGroup, Student student) throws IOException, ClassNotFoundException, FileNotFoundException, AddStudentException
	{
		File file = new File("archives\\" + numberGroup + ".xml");
		deserializeSet(new FileInputStream(file));
		if(students.contains(student)) throw new AddStudentException(student.getName() + " "+ student.getSurName());
		file.delete();
		students.add(student);
		serializeSet(students,new FileOutputStream(file));
		
	}
	
	public void addStudent(int numberGroup, String name, String surName, char task1, char task2, char task3) throws ClassNotFoundException, FileNotFoundException, IOException, AddStudentException
	{
		if((task1 != '+' && task1 !='-') || (task2 != '+' && task2 !='-') || (task3 != '+' && task3 !='-')) throw new IllegalArgumentException();
		addStudent(numberGroup, new Student(name, surName, task1, task2, task3));
	}
	
	public void deleteStudent(int numberGroup, String name, String surName) throws IOException, ClassNotFoundException, FileNotFoundException
	{
		File file = new File("archives\\" + numberGroup + ".xml");
		deserializeSet(new FileInputStream(file));
		file.delete();
		for(Student student: students){
			if(name.equals(student.getName()) && surName.equals(student.getSurName())){
				students.remove(student);
				break;
			}
		}
		serializeSet(students,new FileOutputStream(file));
	}
	
	public Student getStudent(int numberGroup, String name, String surName) throws ClassNotFoundException, FileNotFoundException, IOException
	{
		File file = new File("archives\\" + numberGroup + ".xml");
		deserializeSet(new FileInputStream(file));
		for(Student student: students){
			if(name.equals(student.getName()) && surName.equals(student.getSurName())){
				return student;
			}
		}
			return null;
	}
	
	public Student findStudent(String name, String surName) throws ClassNotFoundException, FileNotFoundException, IOException
	{
		File[] files = (new File("archives")).listFiles();
		for(int i=0; i<files.length; i++)           
		{
		     if(files[i].isFile()){
		    	deserializeSet(new FileInputStream(files[i]));
		 		for(Student student: students){
		 			if(name.equals(student.getName()) && surName.equals(student.getSurName())){
		 				return student;
		 			}
		 		}
		     }
		}
		return null;
	}
	
	public void newGroup(int numberGroup) throws IOException, AddGroupException
	{
		XStream xoutstream = new XStream(new DomDriver());
		File file = new File("archives\\" + numberGroup + ".xml");
		if(file.exists()) throw new AddGroupException(String.valueOf(numberGroup));
		FileOutputStream writer = new FileOutputStream(file);
        ObjectOutputStream out = xoutstream.createObjectOutputStream(writer, "hashSet");
        out.writeObject(new HashSet<Student>());
        out.close();	
	}
	
	public void deleteGroup(int numberGroup) throws FileNotFoundException
	{
		File file = new File("archives\\" + numberGroup + ".xml");
		file.delete();
	}
	
	public Set<Student> getGroup(int numberGroup) throws ClassNotFoundException, FileNotFoundException, IOException
	{
		File file = new File("archives\\" + numberGroup + ".xml");
		deserializeSet(new FileInputStream(file));
		return students;
	}
}
